home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / nxyplot / Source / ErrorBarHandler.m < prev    next >
Text File  |  1992-07-20  |  11KB  |  358 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "ErrorBarHandler.h"
  5. #import "Plot.h"
  6. #import "defs.h"
  7. #import <appkit/Font.h>
  8. #import <appkit/Panel.h>
  9. #import <appkit/Window.h>
  10. #import <appkit/Matrix.h>
  11. #import <appkit/View.h>
  12. #import <appkit/ButtonCell.h>
  13. #import <dpsclient/wraps.h>
  14. #import <appkit/color.h>    /* only for "blanking out" parts of a matrix */
  15. #import <appkit/graphics.h>    /* ditto */
  16.  
  17. /*
  18.  * The job of this object is to keep the appearance of the Error Bar panel in
  19.  * accord with the state of the program.  This is only needed if the Error Bar
  20.  * panel is visible.  A lot of the code is the same as in ColumnSelectionHandler.m.
  21.  */
  22.  
  23. @implementation ErrorBarHandler
  24.  
  25. - init
  26. {
  27. /*
  28.  * This global variable keeps track of whether the error bar window
  29.  * has ever been displayed.  We can avoid updating after the selective
  30.  * file removal if we have never been displayed.
  31.  */ 
  32.   everVisible = NO;
  33.   return self;
  34. }
  35.  
  36. - eraseDisabledCells:sender
  37. {
  38.   int n, j, numrows, numcols, ncurves;
  39.   NXRect r;
  40.   BOOL exbars, eybars;
  41.  
  42.   [errorBarMatrix getNumRows:&numrows numCols:&numcols];
  43.   [errorBarMatrix lockFocus];
  44.   NXSetColor([errorBarMatrix backgroundColor]); /* cf. comment in ColumnSelectionHandler.m */
  45.   for (n=0; n<[plotParam nFiles]; n++) {
  46.     exbars = [plotParam has_exbars:n];
  47.     eybars = [plotParam has_eybars:n];
  48.     if (!exbars && !eybars) {
  49.       /* if this file has no error bars, blank out everything */
  50.       for (j=-1; j<numcols; j++) {
  51.         [errorBarMatrix getCellFrame:&r at:n :j+1]; /* note the j+1 here and below */
  52.         NXRectFill(&r);
  53.       }
  54.     }
  55.     else if (exbars && !eybars) {
  56.       /* x error bars, no y error bars, blank out some columns  */
  57.       for (j=0; j<numcols; j++) {
  58.         [errorBarMatrix getCellFrame:&r at:n :j+1];
  59.         NXRectFill(&r);
  60.       }
  61.     }
  62.     else if (!exbars && eybars) {
  63.       /* no x error bars, has y error bars; blank out 1st and some more columns */
  64.       [errorBarMatrix getCellFrame:&r at:n :0];
  65.       NXRectFill(&r);
  66.       ncurves = [plotParam nCurves:n];
  67.       if (ncurves < numcols) {
  68.     for (j=ncurves; j<numcols; j++) {
  69.       [errorBarMatrix getCellFrame:&r at:n :j+1];
  70.       NXRectFill(&r);
  71.     }
  72.       }
  73.     }
  74.     else {
  75.       /* both x and y error bars; maybe blank out some columns */
  76.       ncurves = [plotParam nCurves:n];
  77.       if (ncurves < numcols) {
  78.     for (j=ncurves; j<numcols; j++) {
  79.       [errorBarMatrix getCellFrame:&r at:n :j+1];
  80.       NXRectFill(&r);
  81.     }
  82.       }
  83.     }
  84.   }
  85.   [errorBarMatrix unlockFocus];
  86.   NXPing();
  87.   return self;
  88. }
  89.  
  90. - removeAll:sender
  91. /* This method is called by the "remove all files" method of the Plot object. */
  92. {
  93.   int n, j;
  94.   int numrows, numcols;
  95.   NXSize cellsize, intercell;
  96.   NXCoord dy;
  97.  
  98.   /* Do something only if the window has ever been displayed  */
  99.   if (everVisible) {
  100.     [errorBarMatrix getNumRows:&numrows numCols:&numcols];
  101.     [errorBarMatrix getCellSize:&cellsize];
  102.     [errorBarMatrix getIntercell:&intercell];
  103.     /*
  104.      * Wipe out everything.
  105.      */
  106.     dy = (NXCoord)(numrows - 1) * (cellsize.height + intercell.height);
  107.     [errorBarMatrix moveBy:0.0 :dy];
  108.     /*
  109.      * Before doing renewRows, set the state of all the cells to 1; this is
  110.      * because the renewRows method just recycles the cells, and later on
  111.      * we may find ourselves using a cell which has state=0 when we don't
  112.      * want such a beast.  Also disable all cells (paranoia strikes).
  113.      */
  114.     for (n=0; n<numrows; n++) {
  115.       for (j=0; j<numcols; j++) {
  116.     [[errorBarMatrix cellAt:n :j] setState:1];
  117.     [[errorBarMatrix cellAt:n :j] setEnabled:YES];
  118.       }
  119.     }
  120.     [errorBarMatrix renewRows:1 cols:1];
  121.     [errorBarMatrix sizeToCells];
  122.     [[errorBarMatrix cellAt:0 :0] setType:NX_TOGGLE];
  123.     [filenameMatrix moveBy:0.0 :dy];
  124.     [filenameMatrix renewRows:1 cols:1];
  125.     [[filenameMatrix cellAt:0 :0] setStringValue:"filename"];
  126.     [filenameMatrix sizeToCells];
  127.     [errorBarText renewRows:1 cols:1];
  128.     [errorBarText sizeToCells];
  129.     /* Do some drawing now.  Display the view. */
  130.     [[errorBarMatrix window] display];
  131.     NXPing();            /* needed??? */
  132.   }
  133.   return self;
  134. }
  135.  
  136.  
  137. - updatePanel:sender
  138. /*
  139.  * The update button activates this method; it is also called from
  140.  * windowDidResize and from Plot.m in postludeToReading.  We have to
  141.  * fix up the error bar panel so that it's correct.
  142.  */
  143. {
  144.   int n, j;
  145.   int nfilestotal = [plotParam nFiles], maxcols = 0, ncurves;
  146.   char title[80];
  147.   int numrows, numcols;
  148.   NXSize cellsize, intercell;
  149.   NXCoord dy;
  150.   int ** turned_on;
  151.   BOOL  exbars, eybars;
  152.  
  153.   if (everVisible == NO) everVisible = YES;
  154.  
  155.  
  156.   [errorBarMatrix getNumRows:&numrows numCols:&numcols];
  157.   [errorBarMatrix getCellSize:&cellsize];
  158.   [errorBarMatrix getIntercell:&intercell];
  159.  
  160.   /*
  161.    * We have to create some additional rows and perhaps some additional columns.
  162.    */
  163.   // First figure out how many columns the matrix should have
  164.   for (n=0; n<nfilestotal; n++) {
  165.     maxcols = MAX(maxcols, [plotParam nCurves:n]);
  166.   }
  167.   maxcols++;            /* add one column for the "x" (zero) column */
  168.  
  169.   if (numrows != nfilestotal  ||  numcols != maxcols) {
  170.     /* The renewRows:cols: message might have the side effect of setting
  171.      * the state of all the cells of the matrix back to 0; this is undesired,
  172.      * so before changing the number of rows and/or columns in the matrix,
  173.      * make sure we remember which cells in each row were turned on.
  174.      */
  175.     turned_on = (int **)malloc(nfilestotal * sizeof(int)); /* should do error check */
  176.     for (n=0; n<nfilestotal; n++) {
  177.       *(turned_on + n) = (int *)malloc(maxcols * sizeof(int));
  178.     }
  179.     for (n=0; n<nfilestotal; n++) {
  180.       for (j=0; j<maxcols; j++) {
  181.     *(*(turned_on+n)+j) = 1;
  182.       }
  183.     }
  184.     for (n=0; n<numrows; n++) {
  185.       for (j=0; j<numcols; j++) {
  186.     *(*(turned_on+n)+j) = [[errorBarMatrix cellAt:n :j] state];
  187.       }
  188.     }
  189.  
  190.     [errorBarMatrix renewRows:nfilestotal cols:maxcols];
  191.  
  192.     for (n=0; n<nfilestotal; n++) {
  193.       for (j=0; j<maxcols; j++) {
  194.     [[errorBarMatrix cellAt:n :j] setState:1]; /* everything turned on */
  195.       }
  196.     }
  197.     /* Turn cells off if needed. */
  198.     for (n=0; n<numrows; n++) {
  199.       for (j=0; j<numcols; j++) {
  200.     [[errorBarMatrix cellAt:n :j] setState:*(*(turned_on+n)+j)];
  201.       }
  202.     }
  203.     for (n=0; n<nfilestotal; n++) {
  204.       free((void *)*(turned_on + n));
  205.     }
  206.     free((void *)turned_on);
  207.   }
  208.   [errorBarMatrix sizeToCells];
  209.   dy = (float)(nfilestotal - numrows) * (cellsize.height + intercell.height);
  210.   [errorBarMatrix moveBy:0.0 :-dy];
  211.   // Some of the cells may come in with type NULLCELL; fix them here
  212.   for (n=0; n<nfilestotal; n++) {
  213.     for (j=0; j<maxcols; j++) {
  214.       [[errorBarMatrix cellAt:n :j] setEnabled:YES];
  215.       [[errorBarMatrix cellAt:n :j] setType:NX_TOGGLE];
  216.     }
  217.   }
  218.   // We surround the [errorBarMatrix display] and [self eraseDisabledCells]
  219.   // calls with the disableFlushWindow, reenableFlushWindow, and flushWindow
  220.   // calls to prevent the disabled matrix cells from being visible for a long
  221.   // time while they're drawn and then erased.
  222.   [errorBarPanel disableFlushWindow];
  223.   [errorBarMatrix display];
  224.   // Disable cells that shouldn't appear.
  225.   for (n=0; n<nfilestotal; n++) {
  226.     exbars = [plotParam has_exbars:n];
  227.     eybars = [plotParam has_eybars:n];
  228.     if (!exbars && !eybars) { 
  229.       /* if this file has no error bars, disable everything */
  230.       for (j=-1; j<maxcols; j++) {
  231.         [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
  232.     [[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
  233.       }
  234.     }
  235.     else if (exbars && !eybars) {
  236.       /* x error bars, no y error bars, blank out some columns  */
  237.       for (j=0; j<numcols; j++) {
  238.     [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
  239.     [[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
  240.       }
  241.     }
  242.     else if (!exbars && eybars) {
  243.       /* no x error bars, has y error bars; blank out 1st and some more columns */
  244.       [[errorBarMatrix cellAt:n :0] setType:NX_NULLCELL];
  245.       [[errorBarMatrix cellAt:n :0] setEnabled:NO];
  246.       ncurves = [plotParam nCurves:n];
  247.       if (ncurves < numcols) {
  248.     for (j=ncurves; j<maxcols; j++) {
  249.       [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
  250.       [[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
  251.     }
  252.       }
  253.     }
  254.     else {
  255.       /* both x and y error bars; maybe blank out some columns */
  256.       ncurves = [plotParam nCurves:n];
  257.       if (ncurves < numcols) {
  258.     for (j=ncurves; j<numcols; j++) {
  259.       [[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
  260.       [[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
  261.     }
  262.       }
  263.     }
  264.   }
  265.  
  266.   // We have to put the makeKeyAndOrderFront before the eraseDisabledCells
  267.   // method, because eraseDisabledCells does a lockFocus and lockFocus needs
  268.   // a real window to draw into.  We put the makeKeyAndOrderFront here rather
  269.   // than at the beginning of this method because this way the disabled cells
  270.   // of the matrix are visible for a shorter period of time.
  271.   [errorBarPanel makeKeyAndOrderFront:self];
  272.  
  273.   // Now erase those disabled cells.
  274.   [self eraseDisabledCells:self];
  275.   [errorBarPanel reenableFlushWindow];
  276.   [errorBarPanel flushWindowIfNeeded];
  277.   NXPing();            /* needed? */
  278.  
  279.   // That finishes with the errorBarMatrix; now for the filename Matrix.
  280.   [filenameMatrix renewRows:nfilestotal cols:1];
  281.   for (n=0; n<nfilestotal; n++) {
  282.     if (!strncmp([plotParam filename:(unsigned)n], "pasteboard", 10))
  283.       sprintf(title, "pasteboard");
  284.     else
  285.       sprintf(title, strrchr([plotParam filename:(unsigned)n], '/') + 1);
  286.     [[filenameMatrix cellAt:n :0] setStringValue:title];
  287.   }
  288.   [filenameMatrix sizeToCells];
  289.   [filenameMatrix moveBy:0.0 :-dy];
  290.   [filenameMatrix display];
  291.  
  292.   // And now for the errorBarText matrix.
  293.   [errorBarText renewRows:1 cols:maxcols];
  294.   for (j=0; j<maxcols; j++) {
  295.     sprintf(title, "%d", j);
  296.     [[errorBarText cellAt:0 :j] setStringValue:title];
  297.   }
  298.   [errorBarText sizeToCells];
  299.   [errorBarText display];
  300.   return self;
  301. }
  302.  
  303.  
  304. /*
  305.  * Apropos this, see the remarks in ColumnSelectionHandler.m
  306.  */
  307. - windowDidResize:sender
  308. {
  309.   [self perform:@selector(updatePanel:)
  310.         with:self
  311.         afterDelay:1        /* wait 0.001 second */
  312.         cancelPrevious:YES];
  313.   return self;
  314. }
  315.  
  316.  
  317. /*
  318.  * This is called by the selective file removal code in Plot.m.
  319.  */
  320. - update:sender
  321. {
  322.   int n, nfilestotal = [plotParam nFiles], num_removed = 0;
  323.   NXSize cellsize, intercell;
  324.   NXCoord dy;
  325.  
  326.   /* Do something only if the window has ever been displayed  */
  327.   if (everVisible) {
  328.     [errorBarMatrix getCellSize:&cellsize];
  329.     [errorBarMatrix getIntercell:&intercell];
  330.     /*
  331.      * Count down the file removal panel, removing rows as needed.
  332.      */
  333.     for (n = nfilestotal-1; n>=0; n--) {
  334.       if ([[fileRemovalButtons cellAt:n :0] state] == 1) {
  335.     /* This file is to be removed. */
  336.     num_removed++;
  337.     [errorBarMatrix removeRowAt:n andFree:YES];
  338.     [filenameMatrix removeRowAt:n andFree:YES];
  339.       }
  340.     }
  341.     [errorBarMatrix sizeToCells];
  342.     [filenameMatrix sizeToCells];
  343.     if (num_removed > 0) {
  344.       dy = (NXCoord)(num_removed) * (cellsize.height + intercell.height);
  345.       [errorBarMatrix moveBy:0.0 :dy];
  346.       [filenameMatrix moveBy:0.0 :dy];
  347.     }
  348.     /* Do some drawing now.  Display the view. */
  349.     [[errorBarMatrix window] display];
  350.     NXPing();            /* needed??? */
  351.   }
  352.  
  353.  
  354.   return self;
  355. }
  356.  
  357. @end
  358.